/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * TypeEditBox.java
 *
 * Created on 13-feb-2011, 17:33:02
 */

package nl.lemval.nododue.dialog;

import java.util.ArrayList;
import javax.swing.DefaultListModel;
import javax.swing.JTextField;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import nl.lemval.nododue.Options;
import nl.lemval.nododue.util.InputRange;
import nl.lemval.nododue.util.listeners.TextFieldUtil;
import org.apache.commons.lang.StringUtils;
import org.jdesktop.application.Action;

/**
 *
 * @author Michael
 */
public class TypeEditBox extends javax.swing.JDialog {
    public static final String NEW_INPUT_RANGE = "<Nieuw>";

    private InputRange current;
    private DefaultListModel typeModel;
    
    /** Creates new form TypeEditBox */
    public TypeEditBox(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        typeModel = new DefaultListModel();
        updateModel();
        initComponents();
    }

    private void updateModel() {
        typeModel.clear();
        ArrayList<InputRange> ranges = Options.getInstance().getInputRanges();
        for (InputRange range : ranges) {
            typeModel.addElement(range);
        }
        ListDataEvent evt = new ListDataEvent(typeModel, ListDataEvent.CONTENTS_CHANGED, 0, typeModel.getSize());
        for (ListDataListener listDataListener : typeModel.getListDataListeners()) {
            listDataListener.contentsChanged(evt);
        }
    }
    
    private InputRange getSelectedRange() {
        Object[] selected = signalList.getSelectedValues();
        if ( selected.length == 1 ) {
            return (InputRange) selected[0];
        }
        return null;
    }

    @Action
    public void close() {
        Options.getInstance().removeInputRange(NEW_INPUT_RANGE);
        setVisible(false);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        closeButton = new javax.swing.JButton();
        detailPanel = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        startLabel = new javax.swing.JLabel();
        endLabel = new javax.swing.JLabel();
        extensionLabel = new javax.swing.JLabel();
        decimalLabel = new javax.swing.JLabel();
        nameField = new javax.swing.JTextField();
        extensionField = new javax.swing.JTextField();
        startField = new javax.swing.JTextField();
        endField = new javax.swing.JTextField();
        decimalField = new javax.swing.JTextField();
        addButton = new javax.swing.JButton();
        removeButton = new javax.swing.JButton();
        listLabel = new javax.swing.JLabel();
        listScrollPanel = new javax.swing.JScrollPane();
        signalList = new javax.swing.JList();
        listLabel1 = new javax.swing.JLabel();
        jButton3 = new javax.swing.JButton();

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(nl.lemval.nododue.NodoDueManager.class).getContext().getActionMap(TypeEditBox.class, this);
        closeButton.setAction(actionMap.get("close")); // NOI18N
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(nl.lemval.nododue.NodoDueManager.class).getContext().getResourceMap(TypeEditBox.class);
        closeButton.setText(resourceMap.getString("closeButton.text")); // NOI18N
        closeButton.setName("closeButton"); // NOI18N

        setTitle(resourceMap.getString("Form.title")); // NOI18N
        setName("Form"); // NOI18N
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                doClose(evt);
            }
        });

        detailPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        detailPanel.setName("detailPanel"); // NOI18N

        nameLabel.setFont(nameLabel.getFont().deriveFont(nameLabel.getFont().getStyle() | java.awt.Font.BOLD));
        nameLabel.setText(resourceMap.getString("nameLabel.text")); // NOI18N
        nameLabel.setName("nameLabel"); // NOI18N

        startLabel.setText(resourceMap.getString("startLabel.text")); // NOI18N
        startLabel.setName("startLabel"); // NOI18N

        endLabel.setText(resourceMap.getString("endLabel.text")); // NOI18N
        endLabel.setName("endLabel"); // NOI18N

        extensionLabel.setText(resourceMap.getString("extensionLabel.text")); // NOI18N
        extensionLabel.setName("extensionLabel"); // NOI18N

        decimalLabel.setText(resourceMap.getString("decimalLabel.text")); // NOI18N
        decimalLabel.setName("decimalLabel"); // NOI18N

        nameField.setText(resourceMap.getString("nameField.text")); // NOI18N
        nameField.setName("nameField"); // NOI18N
        nameField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                fieldFocusLost(evt);
            }
        });

        extensionField.setText(resourceMap.getString("extensionField.text")); // NOI18N
        extensionField.setName("extensionField"); // NOI18N
        extensionField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                fieldFocusLost(evt);
            }
        });

        startField.setText(resourceMap.getString("startField.text")); // NOI18N
        startField.setName("startField"); // NOI18N
        startField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                fieldFocusLost(evt);
            }
        });
        startField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                decimalFieldTyped(evt);
            }
        });

        endField.setText(resourceMap.getString("endField.text")); // NOI18N
        endField.setName("endField"); // NOI18N
        endField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                fieldFocusLost(evt);
            }
        });
        endField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                decimalFieldTyped(evt);
            }
        });

        decimalField.setText(resourceMap.getString("decimalField.text")); // NOI18N
        decimalField.setName("decimalField"); // NOI18N
        decimalField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                fieldFocusLost(evt);
            }
        });
        decimalField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                integerFieldTyped(evt);
            }
        });

        addButton.setText(resourceMap.getString("addButton.text")); // NOI18N
        addButton.setName("addButton"); // NOI18N
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addType(evt);
            }
        });

        removeButton.setText(resourceMap.getString("removeButton.text")); // NOI18N
        removeButton.setName("removeButton"); // NOI18N
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeType(evt);
            }
        });

        javax.swing.GroupLayout detailPanelLayout = new javax.swing.GroupLayout(detailPanel);
        detailPanel.setLayout(detailPanelLayout);
        detailPanelLayout.setHorizontalGroup(
            detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(detailPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(detailPanelLayout.createSequentialGroup()
                        .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(decimalLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE)
                            .addComponent(extensionLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(startLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(endLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(decimalField, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
                            .addComponent(endField, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
                            .addComponent(extensionField, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
                            .addComponent(startField, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
                            .addComponent(nameField, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, detailPanelLayout.createSequentialGroup()
                        .addComponent(removeButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(addButton)))
                .addContainerGap())
        );
        detailPanelLayout.setVerticalGroup(
            detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(detailPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(nameLabel)
                    .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(extensionLabel)
                    .addComponent(extensionField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(startLabel)
                    .addComponent(startField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(endLabel)
                    .addComponent(endField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(decimalLabel)
                    .addComponent(decimalField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 40, Short.MAX_VALUE)
                .addGroup(detailPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addButton)
                    .addComponent(removeButton))
                .addContainerGap())
        );

        listLabel.setFont(listLabel.getFont().deriveFont(listLabel.getFont().getStyle() | java.awt.Font.BOLD));
        listLabel.setText(resourceMap.getString("listLabel.text")); // NOI18N
        listLabel.setName("listLabel"); // NOI18N

        listScrollPanel.setName("listScrollPanel"); // NOI18N

        signalList.setModel(typeModel);
        signalList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        signalList.setName("typeList"); // NOI18N
        signalList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                signalListselectionChanged(evt);
            }
        });
        listScrollPanel.setViewportView(signalList);

        listLabel1.setFont(listLabel1.getFont().deriveFont(listLabel1.getFont().getStyle() | java.awt.Font.BOLD));
        listLabel1.setText(resourceMap.getString("listLabel1.text")); // NOI18N
        listLabel1.setName("listLabel1"); // NOI18N

        jButton3.setAction(actionMap.get("close")); // NOI18N
        jButton3.setText(resourceMap.getString("jButton3.text")); // NOI18N
        jButton3.setName("jButton3"); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(listScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(detailPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(listLabel1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(343, Short.MAX_VALUE)
                .addComponent(jButton3)
                .addContainerGap())
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 190, Short.MAX_VALUE)
                    .addComponent(listLabel)
                    .addGap(0, 190, Short.MAX_VALUE)))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(listLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(detailPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(listScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE))
                .addGap(15, 15, 15)
                .addComponent(jButton3)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 153, Short.MAX_VALUE)
                    .addComponent(listLabel)
                    .addGap(0, 153, Short.MAX_VALUE)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void signalListselectionChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_signalListselectionChanged
        if (evt.getValueIsAdjusting() == false) {
            InputRange range = getSelectedRange();
            if ( range != null ) {
                nameField.setText(range.getName());
                extensionField.setText(range.getPostfix());
                startField.setText(String.valueOf(range.getStart()));
                endField.setText(String.valueOf(range.getEnd()));
                decimalField.setText(String.valueOf(range.getDecimals()));
                current = range;
            }
        }
}//GEN-LAST:event_signalListselectionChanged

    private void fieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_fieldFocusLost
        if ( current != null ) {
            current.setName(nameField.getText());
            current.setPostfix(extensionField.getText());
            try {
                current.setDecimals(Integer.parseInt(decimalField.getText()));
            } catch (NumberFormatException e) {}
            try {
                current.setStart(Double.parseDouble(startField.getText()));
            } catch (NumberFormatException e) {}
            try {
                current.setEnd(Double.parseDouble(endField.getText()));
            } catch (NumberFormatException e) {}
        }
        Options.getInstance().addInputRange(current);
    }//GEN-LAST:event_fieldFocusLost

    private void decimalFieldTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_decimalFieldTyped
        JTextField tf = (JTextField) evt.getSource();
        char typed = evt.getKeyChar();
        String text = TextFieldUtil.determineValue(tf, typed);
        if ( StringUtils.isBlank(text) || "-".equals(text) ) { return; }
        try {
            Double.parseDouble(text);
            return;
        } catch (Exception e) {
            // Fall through
        }
        evt.consume();
    }//GEN-LAST:event_decimalFieldTyped

    private void integerFieldTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_integerFieldTyped
        JTextField tf = (JTextField) evt.getSource();
        char typed = evt.getKeyChar();
        String text = TextFieldUtil.determineValue(tf, typed);
        if ( StringUtils.isBlank(text) ) { return; }
        try {
            int value = Integer.parseInt(text);
            if ( value >= 0 ) {
                return;
            }
        } catch (Exception e) {
            // Fall through
        }
        evt.consume();
    }//GEN-LAST:event_integerFieldTyped

    private void addType(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addType
        InputRange range = new InputRange(NEW_INPUT_RANGE, 0, 255, 0, "", 2);
        Options.getInstance().addInputRange(range);
        updateModel();
    }//GEN-LAST:event_addType

    private void removeType(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeType
        Options.getInstance().removeInputRange(nameField.getText());
        updateModel();
    }//GEN-LAST:event_removeType

    private void doClose(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_doClose
        Options.getInstance().removeInputRange(NEW_INPUT_RANGE);
    }//GEN-LAST:event_doClose

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JButton closeButton;
    private javax.swing.JTextField decimalField;
    private javax.swing.JLabel decimalLabel;
    private javax.swing.JPanel detailPanel;
    private javax.swing.JTextField endField;
    private javax.swing.JLabel endLabel;
    private javax.swing.JTextField extensionField;
    private javax.swing.JLabel extensionLabel;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel listLabel;
    private javax.swing.JLabel listLabel1;
    private javax.swing.JScrollPane listScrollPanel;
    private javax.swing.JTextField nameField;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JButton removeButton;
    private javax.swing.JList signalList;
    private javax.swing.JTextField startField;
    private javax.swing.JLabel startLabel;
    // End of variables declaration//GEN-END:variables

}
